import { Inject, Provide } from '@midwayjs/core';
import { Context } from '@midwayjs/koa';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository } from 'typeorm';
import {
  CreateTeacherVolunteerDto,
  UpdateTeacherVolunteerDto,
  QueryTeacherVolunteerDto,
  DeleteTeacherVolunteerDto,
} from '@dto/teacherVolunteerTeam.dto';
import { TeacherVolunteerTeamEntity } from '@entity/teacherVolunteerTeam.entity';
import { GroupEntity } from '@entity/group.entity';
import { TeamEntity } from '@entity/team.entity';
import { TeacherEntity } from '@entity/teacher.entity';
import { resBuild } from '../utils/resBuild';
import { isEmpty } from '../utils';

@Provide()
export class TeacherVolunteerTeamDao {
  @Inject()
  ctx: Context;

  @InjectEntityModel(TeacherVolunteerTeamEntity)
  teacherVolunteerTeamEntityRep: Repository<TeacherVolunteerTeamEntity>;

  @InjectEntityModel(GroupEntity)
  groupEntityRep: Repository<GroupEntity>;

  @InjectEntityModel(TeamEntity)
  teamEntityRep: Repository<TeamEntity>;

  @InjectEntityModel(TeacherEntity)
  teacherEntityRep: Repository<TeacherEntity>;

  /**
   * 创建/更新教师志愿（先删除旧的，再插入新的）
   */
  async create(createDto: CreateTeacherVolunteerDto) {
    const { groupId, teacherId, teams } = createDto;

    // 1. 校验分组是否存在且未过期
    const group = await this.groupEntityRep.findOne({
      where: { groupId },
    });
    if (!group) {
      throw new Error('该分组不存在');
    }
    if (new Date(group.endTime) < new Date()) {
      throw new Error('该分组已经结束，不能创建志愿');
    }

    // 2. 校验教师是否存在
    const teacher = await this.teacherEntityRep.findOne({
      where: { teacherId, delFlag: '0' },
    });
    if (!teacher) {
      throw new Error('教师不存在');
    }

    // 3. 校验队伍是否都存在且属于该分组
    const teamIds = teams.map(t => t.teamId);
    const teamsInDb = await this.teamEntityRep.find({
      where: { groupId, delFlag: '0' },
      select: ['teamId'],
    });
    const validTeamIds = teamsInDb.map(t => t.teamId);
    const invalidTeamIds = teamIds.filter(id => !validTeamIds.includes(id));
    if (invalidTeamIds.length > 0) {
      throw new Error(`队伍 ${invalidTeamIds.join(', ')} 不存在或不属于该分组`);
    }

    // 4. 使用事务：删除旧志愿 + 插入新志愿
    return await this.teacherVolunteerTeamEntityRep.manager.transaction(
      async manager => {
        const repo = manager.getRepository(TeacherVolunteerTeamEntity);

        // 删除该教师在该分组的所有旧志愿
        await repo.delete({ groupId, teacherId });

        // 插入新志愿
        const entities = teams.map(t =>
          repo.create({
            groupId,
            teacherId,
            teamId: t.teamId,
            sort: t.sort,
          })
        );
        await repo.save(entities);

        return resBuild.success('志愿保存成功');
      }
    );
  }

  /**
   * 更新教师志愿
   */
  async update(updateDto: UpdateTeacherVolunteerDto) {
    return await this.create(updateDto);
  }

  /**
   * 查询教师志愿列表
   */
  async list(query: QueryTeacherVolunteerDto) {
    const qb = this.teacherVolunteerTeamEntityRep
      .createQueryBuilder('entity')
      .leftJoinAndSelect('entity.group', 'group')
      .leftJoinAndSelect('entity.teacher', 'teacher')
      .leftJoinAndSelect('entity.team', 'team')
      .leftJoinAndSelect('teacher.user', 'teacherUser')
      .leftJoinAndSelect('team.studentTeams', 'studentTeams')
      .leftJoinAndSelect('studentTeams.student', 'student')
      .leftJoinAndSelect('student.user', 'studentUser')
      .where('teacher.delFlag = :teacherDelFlag', { teacherDelFlag: '0' })
      .andWhere('team.delFlag = :teamDelFlag', { teamDelFlag: '0' })
      .andWhere('group.delFlag = :groupDelFlag', { groupDelFlag: '0' });

    // 精确查询
    if (!isEmpty(query.groupId)) {
      qb.andWhere('entity.groupId = :groupId', { groupId: query.groupId });
    }
    if (!isEmpty(query.teacherId)) {
      qb.andWhere('entity.teacherId = :teacherId', {
        teacherId: query.teacherId,
      });
    }
    if (!isEmpty(query.teamId)) {
      qb.andWhere('entity.teamId = :teamId', { teamId: query.teamId });
    }

    // 模糊搜索
    if (!isEmpty(query.groupName)) {
      qb.andWhere('group.groupName LIKE :groupName', {
        groupName: `%${query.groupName}%`,
      });
    }
    if (!isEmpty(query.teamName)) {
      qb.andWhere('team.teamName LIKE :teamName', {
        teamName: `%${query.teamName}%`,
      });
    }

    // 分页
    if (query.pageNum && query.pageSize) {
      qb.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }

    // 排序：按志愿顺序升序
    qb.orderBy('entity.sort', 'ASC');
    qb.addOrderBy('entity.groupId', 'DESC');

    const [rows, total] = await qb.getManyAndCount();
    return resBuild.list(rows, total);
   }

  /**
   * 获取教师的所有分组及其志愿详情
   */
  async getVolunteerDetail(teacherId: number) {
    // 1. 查询该教师所属的所有分组
    const groups = await this.groupEntityRep
      .createQueryBuilder('entity')
      .leftJoinAndSelect('entity.grade', 'grade')
      .leftJoinAndSelect('entity.dept', 'dept')
      .andWhere('entity.teacherIds LIKE :teacherIds', {
        teacherIds: `%${teacherId}%`,
      })
      .andWhere('entity.delFlag = :delFlag', { delFlag: '0' })
      .orderBy('entity.createTime', 'DESC')
      .getMany();

    // 2. 为每个分组加载该教师的志愿详情
    const result = await Promise.all(
      groups.map(async group => {
        // 查询该教师在该分组的志愿列表（包含队伍和学生信息）
        const volunteers = await this.teacherVolunteerTeamEntityRep
          .createQueryBuilder('entity')
          .leftJoinAndSelect('entity.team', 'team')
          .leftJoinAndSelect('team.studentTeams', 'studentTeams')
          .leftJoinAndSelect('team.teamTeachers', 'teamTeachers')
          .leftJoinAndSelect('studentTeams.student', 'student')
          .leftJoinAndSelect('student.user', 'studentUser')
          .leftJoinAndSelect('student.major', 'studentMajor')
          .where('entity.groupId = :groupId', { groupId: group.groupId })
          .andWhere('entity.teacherId = :teacherId', { teacherId })
          .andWhere('team.delFlag = :teamDelFlag', { teamDelFlag: '0' })
          .orderBy('entity.sort', 'ASC')
          .getMany();

        // 将志愿详情附加到分组对象上
        return {
          ...group,
          volunteers, // 志愿列表（按 sort 排序）
        };
      })
    );

    return resBuild.data(result);
  }





  /**
   * 查询教师在某个分组的志愿详情
   */
  async detail(groupId: number, teacherId: number) {
    const qb = this.teacherVolunteerTeamEntityRep
      .createQueryBuilder('entity')
      .leftJoinAndSelect('entity.group', 'group')
      .leftJoinAndSelect('entity.teacher', 'teacher')
      .leftJoinAndSelect('entity.team', 'team')
      .leftJoinAndSelect('teacher.user', 'teacherUser')
      .leftJoinAndSelect('team.studentTeams', 'studentTeams')
      .leftJoinAndSelect('studentTeams.student', 'student')
      .leftJoinAndSelect('student.user', 'studentUser')
      .where('entity.groupId = :groupId', { groupId })
      .andWhere('entity.teacherId = :teacherId', { teacherId })
      .andWhere('teacher.delFlag = :teacherDelFlag', { teacherDelFlag: '0' })
      .andWhere('team.delFlag = :teamDelFlag', { teamDelFlag: '0' })
      .andWhere('group.delFlag = :groupDelFlag', { groupDelFlag: '0' })
      .orderBy('entity.sort', 'ASC');

    const rows = await qb.getMany();
    return resBuild.data(rows);
  }

  /**
   * 删除教师的某些志愿
   */
  async remove(deleteDto: DeleteTeacherVolunteerDto) {
    const { groupId, teacherId, teamIds } = deleteDto;

    return await this.teacherVolunteerTeamEntityRep.manager.transaction(
      async manager => {
        const repo = manager.getRepository(TeacherVolunteerTeamEntity);

        // 删除指定的志愿
        for (const teamId of teamIds) {
          await repo.delete({ groupId, teacherId, teamId });
        }

        return resBuild.success('删除成功');
      }
    );
  }

  /**
   * 删除教师在某个分组的所有志愿
   */
  async removeAll(groupId: number, teacherId: number) {
    await this.teacherVolunteerTeamEntityRep.delete({ groupId, teacherId });
    return resBuild.success('删除成功');
  }
}
